home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / show / mpeg_player122.lha / src / util.c < prev    next >
C/C++ Source or Header  |  1992-12-08  |  10KB  |  443 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. #include "video.h"
  22. #include "util.h"
  23.  
  24. /* Declarations of global variables used. */
  25.  
  26. unsigned int curBits;
  27. int bitOffset;
  28. int bufLength;
  29. unsigned int *bitBuffer;
  30.  
  31. /* Bit masks used by bit i/o operations. */
  32.  
  33. unsigned int nBitMask[] = { 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 
  34.                 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 
  35.                 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 
  36.                 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 
  37.                 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 
  38.                 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 
  39.                 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 
  40.                 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe};
  41.  
  42. unsigned int bitMask[] = {  0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff, 
  43.                 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
  44.                 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
  45.                 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
  46.                 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
  47.                 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
  48.                 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
  49.                 0x0000000f, 0x00000007, 0x00000003, 0x00000001};
  50.  
  51. unsigned int rBitMask[] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 
  52.                 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 
  53.                 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, 
  54.                 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 
  55.                 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, 
  56.                 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 
  57.                 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, 
  58.                 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000};
  59.  
  60. unsigned int bitTest[] = {  0x80000000, 0x40000000, 0x20000000, 0x10000000, 
  61.                 0x08000000, 0x04000000, 0x02000000, 0x01000000,
  62.                 0x00800000, 0x00400000, 0x00200000, 0x00100000,
  63.                 0x00080000, 0x00040000, 0x00020000, 0x00010000,
  64.                 0x00008000, 0x00004000, 0x00002000, 0x00001000,
  65.                 0x00000800, 0x00000400, 0x00000200, 0x00000100,
  66.                 0x00000080, 0x00000040, 0x00000020, 0x00000010,
  67.                 0x00000008, 0x00000004, 0x00000002, 0x00000001};
  68.  
  69.  
  70. /*
  71.  *--------------------------------------------------------------
  72.  *
  73.  * correct_underflow --
  74.  *
  75.  *    Called when buffer does not have sufficient data to 
  76.  *      satisfy request for bits.
  77.  *      Calls get_more_data, an application specific routine
  78.  *      required to fill the buffer with more data.
  79.  *
  80.  * Results:
  81.  *      None really.
  82.  *  
  83.  * Side effects:
  84.  *    buf_length and buffer fields in curVidStream structure
  85.  *      may be changed.
  86.  *
  87.  *--------------------------------------------------------------
  88.  */
  89.  
  90. void 
  91. correct_underflow() {
  92.  
  93.   int status;
  94.  
  95.   status = get_more_data(curVidStream->buf_start,
  96.              curVidStream->max_buf_length,
  97.              &bufLength, &bitBuffer);
  98.  
  99.   if (status  < 0) {
  100.     fprintf (stderr, "\n");
  101.     perror("Unexpected read error.");
  102.     exit(1);
  103.   }
  104.   else if ((status == 0) && (bufLength < 1)) {
  105.     fprintf(stderr, "\nUnexepect EOF.\n");
  106. #ifdef ANALYSIS
  107.     PrintAllStats();
  108. #endif
  109.     PrintTimeInfo();
  110.  
  111.     if (loopFlag) longjmp(env, 1);
  112.     DestroyVidStream(curVidStream);
  113.     exit(1);
  114.   }
  115.   curBits = *bitBuffer;
  116.  
  117. }
  118.  
  119.  
  120. /*
  121.  *--------------------------------------------------------------
  122.  *
  123.  * next_bits --
  124.  *
  125.  *    Compares next num bits to low order position in mask.
  126.  *      Buffer pointer is NOT advanced.
  127.  *
  128.  * Results:
  129.  *    TRUE, FALSE, or error code.
  130.  *
  131.  * Side effects:
  132.  *    None.
  133.  *
  134.  *--------------------------------------------------------------
  135.  */
  136.  
  137. int next_bits(num, mask)
  138. int num;
  139. unsigned int mask;
  140. {
  141.   unsigned int stream;
  142.   int ret_value;
  143.  
  144.   /* If no current stream, return error. */
  145.  
  146.   if (curVidStream == NULL)
  147.     return NO_VID_STREAM;
  148.  
  149.   /* Get next num bits, no buffer pointer advance. */
  150.  
  151.   show_bitsn(num, &stream);
  152.  
  153.   /* Compare bit stream and mask. Set return value toTRUE if equal, FALSE if
  154.      differs. 
  155.   */
  156.  
  157.   if (mask == stream) {
  158.     ret_value = TRUE;
  159.   } else ret_value = FALSE;
  160.  
  161.   /* Return return value. */
  162.  
  163.   return ret_value;
  164. }
  165.  
  166.  
  167. /*
  168.  *--------------------------------------------------------------
  169.  *
  170.  * get_ext_data --
  171.  *
  172.  *    Assumes that bit stream is at begining of extension
  173.  *      data. Parses off extension data into dynamically 
  174.  *      allocated space until start code is hit. 
  175.  *
  176.  * Results:
  177.  *    Pointer to dynamically allocated memory containing
  178.  *      extension data.
  179.  *
  180.  * Side effects:
  181.  *    Bit stream irreversibly parsed.
  182.  *
  183.  *--------------------------------------------------------------
  184.  */
  185.  
  186. char *get_ext_data ()
  187. {
  188.   int size, marker;
  189.   char *dataPtr;
  190.   unsigned int data;
  191.  
  192.   /* Set initial ext data buffer size. */
  193.  
  194.   size = EXT_BUF_SIZE;
  195.  
  196.   /* Allocate ext data buffer. */
  197.  
  198.   dataPtr = (char *) malloc(size);
  199.  
  200.   /* Initialize marker to keep place in ext data buffer. */
  201.  
  202.   marker = 0;
  203.  
  204.   /* While next data is not start code... */
  205.   while (!next_bits(24, 0x000001)) {
  206.  
  207.     /* Get next byte of ext data. */
  208.  
  209.     get_bits8(&data);
  210.  
  211.     /* Put ext data into ext data buffer. Advance marker. */
  212.  
  213.     dataPtr[marker] = (char) data;
  214.     marker++;
  215.  
  216.     /* If end of ext data buffer reached, resize data buffer. */
  217.  
  218.     if (marker == size) {
  219.       size += EXT_BUF_SIZE;
  220.       dataPtr = (char *) realloc(dataPtr, size);
  221.     }
  222.   }
  223.  
  224.   /* Realloc data buffer to free any extra space. */
  225.  
  226.   dataPtr = (char *) realloc(dataPtr, marker);
  227.  
  228.   /* Return pointer to ext data buffer. */
  229.  
  230.   return dataPtr;
  231. }
  232.  
  233.  
  234. /*
  235.  *--------------------------------------------------------------
  236.  *
  237.  * next_start_code --
  238.  *
  239.  *    Parses off bitstream until start code reached. When done
  240.  *      next 4 bytes of bitstream will be start code. Bit offset
  241.  *      reset to 0.
  242.  *
  243.  * Results:
  244.  *    Status code.
  245.  *
  246.  * Side effects:
  247.  *    Bit stream irreversibly parsed.
  248.  *
  249.  *--------------------------------------------------------------
  250.  */
  251.  
  252. int next_start_code()
  253. {
  254.   int state;
  255.   int byteoff;
  256.   unsigned int data;
  257.  
  258.   /* If no current stream, return error. */
  259.  
  260.   if (curVidStream == NULL)
  261.     return NO_VID_STREAM;
  262.  
  263.   /* If insufficient buffer length, correct underflow. */
  264.  
  265.   if (bufLength < 2) {
  266.     correct_underflow();
  267.   }
  268.  
  269.   /* If bit offset not zero, reset and advance buffer pointer. */
  270.  
  271.   byteoff = bitOffset % 8;
  272.  
  273.   if (byteoff != 0) {
  274.     bitOffset += (8-byteoff);
  275.     if (bitOffset > 31) {
  276.       bitBuffer++;
  277.       curBits = *bitBuffer;
  278.       bufLength--;
  279.       bitOffset = 0;
  280.     }
  281.   }
  282.  
  283.   /* Set state = 0. */
  284.  
  285.   state = 0;
  286.  
  287.   /* While buffer has data ... */
  288.  
  289.   while(bufLength > 0) {
  290.  
  291.     /* If insufficient data exists, correct underflow. */
  292.  
  293.     if (bufLength < 2) {
  294.       correct_underflow();
  295.     }
  296.  
  297.     /* If next byte is zero... */
  298.  
  299.     get_bits8(&data);
  300.  
  301.     if (data == 0) {
  302.  
  303.       /* If state < 2, advance state. */
  304.  
  305.       if (state < 2) state++;
  306.     }
  307.  
  308.     /* If next byte is one... */
  309.  
  310.     else if (data == 1) {
  311.  
  312.       /* If state == 2, advance state (i.e. start code found). */
  313.  
  314.       if (state == 2) state++;
  315.  
  316.       /* Otherwise, reset state to zero. */
  317.  
  318.       else state = 0;
  319.     }
  320.  
  321.     /* Otherwise byte is neither 1 or 0, reset state to 0. */
  322.  
  323.     else {
  324.       state = 0;
  325.     }
  326.  
  327.     /* If state == 3 (i.e. start code found)... */
  328.  
  329.     if (state == 3) {
  330.  
  331.       /* Set buffer pointer back and reset length & bit offsets so
  332.      next bytes will be beginning of start code. 
  333.       */
  334.  
  335.       bitOffset = bitOffset - 24;
  336.  
  337. #ifdef ANALYSIS
  338.       bitCount -= 3;
  339. #endif ANALYSIS
  340.  
  341.       if (bitOffset < 0) {
  342.     bitOffset = 32 + bitOffset;
  343.     bufLength++;
  344.     bitBuffer--;
  345.     curBits = *bitBuffer;
  346.       }
  347.  
  348.       /* Return success. */
  349.  
  350.       return OK;
  351.     }
  352.   }
  353.  
  354.   /* Return underflow error. */
  355.  
  356.   return UNDERFLOW;
  357. }
  358.  
  359.  
  360. /*
  361.  *--------------------------------------------------------------
  362.  *
  363.  * get_extra_bit_info --
  364.  *
  365.  *    Parses off extra bit info stream into dynamically 
  366.  *      allocated memory. Extra bit info is indicated by
  367.  *      a flag bit set to 1, followed by 8 bits of data.
  368.  *      This continues until the flag bit is zero. Assumes
  369.  *      that bit stream set to first flag bit in extra
  370.  *      bit info stream.
  371.  *
  372.  * Results:
  373.  *    Pointer to dynamically allocated memory with extra
  374.  *      bit info in it. Flag bits are NOT included.
  375.  *
  376.  * Side effects:
  377.  *    Bit stream irreversibly parsed.
  378.  *
  379.  *--------------------------------------------------------------
  380.  */
  381.  
  382. char *get_extra_bit_info ()
  383. {
  384.   int size, marker;
  385.   char *dataPtr;
  386.   unsigned int data;
  387.  
  388.   /* Get first flag bit. */
  389.   get_bits1(&data);
  390.  
  391.   /* If flag is false, return NULL pointer (i.e. no extra bit info). */
  392.  
  393.   if (!data) return NULL;
  394.  
  395.   /* Initialize size of extra bit info buffer and allocate. */
  396.  
  397.   size = EXT_BUF_SIZE;
  398.   dataPtr = (char *) malloc(size);
  399.  
  400.   /* Reset marker to hold place in buffer. */
  401.  
  402.   marker = 0;
  403.  
  404.   /* While flag bit is true. */
  405.  
  406.   while (data) {
  407.  
  408.     /* Get next 8 bits of data. */
  409.     get_bits8(&data);
  410.  
  411.     /* Place in extra bit info buffer. */
  412.  
  413.     dataPtr[marker] = (char) data;
  414.     marker++;
  415.  
  416.     /* If buffer is full, reallocate. */
  417.  
  418.     if (marker == size) {
  419.       size += EXT_BUF_SIZE;
  420.       dataPtr = (char *) realloc(dataPtr, size);
  421.     }
  422.  
  423.     /* Get next flag bit. */
  424.     get_bits1(&data);
  425.   }
  426.  
  427.   /* Reallocate buffer to free extra space. */
  428.  
  429.   dataPtr = (char *) realloc(dataPtr, marker);
  430.  
  431.   /* Return pointer to extra bit info buffer. */
  432.  
  433.   return dataPtr;
  434. }
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.